Like any kind of apps, there are difficult issues to solve when we write Node apps.
In this article, we’ll look at some solutions to common problems when writing Node apps.
Avoid the async/await Inside of a new Promise() Constructor Antipattern
We should avoid the asyhc
and await
inside of the Promise
constructor antipattern.
For instance, instead of writing:
const createPromise = () => {
return new Promise(async (resolve, reject) => {
const val = await Promise.resolve(100);
//..
});
}
We don’t have to have an async
function inside a promise because we shouldn’t have promises inside the Promise
constructor.
async
functions already return promises, so we don’t need the Promise
constructor to turn the code into a promise.
We just move the async
function out of the Promise
and use that as is.
Update All Clients Using Socket.io
We can update all clients with socket.io by using the emit
method.
For instance, we can write:
socket.emit('message', 'hello');
We emit the message
event to all clients with the content 'hello'
.
We can also use the io.sockets.emit
method to emit to all sockets.
For instance, we can write:
io.sockets.emit('`message`', 'hello');
And we can use the broadcast
property to do the same thing.
It sends a message to everyone except for the socket that’s sending the event:
socket.broadcast.emit('`message`', 'hello');
Get Response from S3 getObject in Node.js
We can call the getObject
method to get the item we want as follows:
const aws = require('aws-sdk');
const s3 = new aws.S3();
const getParams = {
Bucket: 'abc',
Key: 'abc.txt'
}
s3.getObject(getParams, (err, data) => {
if (err) {
return err;
}
const objectData = data.Body.toString('utf-8');
});
We use the aws.S3
constructor to create a new client.
Then we set the parameters for setting the bucket and key, which is the file path.
Next, we call getObject
to get the file with the given path in that bucket.
err
is the error object.
data
is the content of the file.
We convert it to a string with toString
and the correct encoding.
Properly Close the Express Server
We call close
on the http
server instance rather than the app
instance.
For instance, we can write:
app.get('/foo', (req, res) => {
res.redirect('/');
setTimeout(() => {
server.close();
}, 3000)
});
const server = app.listen(3000);
We call close
on server
, which is the http
server instance.
app.listen
returns the http
server instance.
Calling a JSON API with Node.js
We can use the http
module’s get
method to make a GET request to a server.
For instance, we can write:
const url = 'https://api.agify.io/?name=michael';
http.get(url, (res) => {
let body = '';
res.on('data', (chunk) => {
body += chunk;
});
res.on('end', () => {
const response = JSON.parse(body);
console.log(response.name);
});
})
.on('error', (e) => {
console.log(e);
});
We called get
by passing in a callback.
The callback listens to the data
event, which gets the data.
We listen to the end
event to parse the JSON when the stream is done emitting data.
In the end
callback, we parse the JSON with JSON.parse
.
We also listen to the error
event to log any errors if they exist.
Selecting Fields for Documents Populated in MongoDB
We can call the populate
method to populate the field that we want and return it.
For instance, we can write:
Model
.findOne({ _id: '...' })
.populate('age', 'name')
We get the item by the _id
, populate the age
and return the name
.
Check if a Function is async
We can check if a function is async by using the Symbol.toStringTag
property.
For instance, we can write:
asyncFn[Symbol.toStringTag] === 'AsyncFunction'
We can also check if it’s an instance of the AsyncFunction
with instanceof
.
For instance, we can write:
const AsyncFunction = (async () => {}).constructor;
const isAsyncFunc = asyncFn instanceof AsyncFunction;
We get the constructor of the async function with the constructor
property.
Then we use the instanceof
operator to do the check.
Conclusion
We shouldn’t put async functions in the Promise
constructor.
We can read a file from the S3 bucket with the getObject
method.
Also, we can make HTTP requests with the http
module.
We can call close
on the http
server instance returned by app.listen
.
There are a few ways to check if a function is async.